package element.synt;

import element.ast.AstNode;
import element.ast.PrimNode;
import element.base.Synt;
import element.base.TreeNode;
import element.base.Word;
import element.base.Wordtype;
import symbal.constsymbal.ConstSymbal;
import table.InterCodeTable;

//PrimaryExp → '(' Exp ')' | LVal | Number
public class PrimaryExp extends Synt {
    private int reg;

    @Override
    public void tointerRP() {
        if (this.getNodes().get(0).isWord(Wordtype.LPARENT)) {
            ((Synt) this.getNodes().get(1)).tointerRP();
        }
    }

    public AstNode toAst() {
        if (this.isConst()) {
            return new PrimNode(this.calcu());
        }
        TreeNode node0 = this.getNodes().get(0);
        if (node0.isWord(Wordtype.LPARENT)) {
            Exp innerexp = (Exp) this.getNodes().get(1);
            return innerexp.toAst();
        } else if (node0 instanceof LVal) {
            return new PrimNode((LVal) node0);
        } else {
            Word inner = ((Number) node0).findFirst();
            int number = Integer.parseInt(inner.getContent());
            return new PrimNode(number);
        }
    }

    public int calcu() {
        TreeNode node0 = this.getNodes().get(0);
        if (node0.isWord(Wordtype.LPARENT)) {
            Exp innerexp = (Exp) this.getNodes().get(1);
            return innerexp.calcu();
        } else if (node0 instanceof LVal) {
            Word ident = ((LVal) node0).findFirst();
            String name = ident.getContent();
            ConstSymbal symbal = InterCodeTable.constTable.findConst(name);
            if (symbal == null) {
                symbal = InterCodeTable.globalTable.findConst(name);
                if (symbal == null) {
                    System.out.println("calcu not const![ident]");
                    System.exit(0);
                }
            }
            return ((LVal) node0).calcu();
        } else {
            Word inner = ((Number) node0).findFirst();
            return Integer.parseInt(inner.getContent());
        }
    }

    public boolean isConst() {
        TreeNode node0 = this.getNodes().get(0);
        if (node0.isWord(Wordtype.LPARENT)) {
            Exp innerexp = (Exp) this.getNodes().get(1);
            return innerexp.isConst();
        } else if (node0 instanceof LVal) {
            return ((LVal) node0).isConst();
        } else {
            return true;
        }
    }
}
